package com.nullpointer.xchatfinal.adapter;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import android.app.AlertDialog;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.androidquery.AQuery;
import com.androidquery.callback.ImageOptions;
import com.nullpointer.xchatfinal.MainActivity;
import com.nullpointer.xchatfinal.R;
import com.nullpointer.xchatfinal.ViewImageActivity;
import com.nullpointer.xchatfinal.object.Friend;
import com.nullpointer.xchatfinal.object.TargetChat;
import com.nullpointer.xchatfinal.object.User;
import com.nullpointer.xchatfinal.object.UserInfo.GenderType;
import com.nullpointer.xchatfinal.utils.Common;
import com.nullpointer.xchatfinal.utils.DataManager;
import com.nullpointer.xchatfinal.utils.KiraGameLog;
import com.nullpointer.xchatfinal.utils.Utils;
import com.quickblox.core.QBEntityCallbackImpl;
import com.quickblox.core.request.QBRequestGetBuilder;
import com.quickblox.core.request.QBRequestUpdateBuilder;
import com.quickblox.customobjects.QBCustomObjects;
import com.quickblox.customobjects.model.QBCustomObject;

public class FriendsAdapter extends ArrayAdapter<Friend> {

	private static class ViewHolder {
		public final LinearLayout rootView;
		public final ImageView ivAvatar;
		public final TextView tvName;
		public final ImageView ivGender;
		public final ImageView ivOnline;
		public final TextView tvStatus;
		public final ImageButton ibOption;
		public final LinearLayout llSendMessage;
		public final LinearLayout llViewProfile;

		private ViewHolder(LinearLayout rootView, ImageView ivAvatar,
				TextView tvName, ImageView ivGender, ImageView ivOnline,
				TextView tvStatus, ImageButton ibOption,
				LinearLayout llSendMessage, LinearLayout llViewProfile) {
			this.rootView = rootView;
			this.ivAvatar = ivAvatar;
			this.tvName = tvName;
			this.ivGender = ivGender;
			this.ivOnline = ivOnline;
			this.tvStatus = tvStatus;
			this.ibOption = ibOption;
			this.llSendMessage = llSendMessage;
			this.llViewProfile = llViewProfile;
		}

		public static ViewHolder create(LinearLayout rootView) {
			ImageView ivAvatar = (ImageView) rootView
					.findViewById(R.id.iv_avatar);
			TextView tvName = (TextView) rootView.findViewById(R.id.tv_name);
			ImageView ivGender = (ImageView) rootView
					.findViewById(R.id.iv_gender);
			ImageView ivOnline = (ImageView) rootView
					.findViewById(R.id.iv_online);
			TextView tvStatus = (TextView) rootView
					.findViewById(R.id.tv_status);
			ImageButton ibOption = (ImageButton) rootView
					.findViewById(R.id.ib_option);
			LinearLayout llSendMessage = (LinearLayout) rootView
					.findViewById(R.id.ll_send_message);
			LinearLayout llViewProfile = (LinearLayout) rootView
					.findViewById(R.id.ll_view_profile);
			return new ViewHolder(rootView, ivAvatar, tvName, ivGender,
					ivOnline, tvStatus, ibOption, llSendMessage, llViewProfile);
		}
	}

	@Override
	public View getView(int position, View convertView, ViewGroup parent) {
		final ViewHolder vh;
		if (convertView == null) {
			View view = mInflater.inflate(R.layout.item_lv_friends, parent,
					false);
			vh = ViewHolder.create((LinearLayout) view);
			view.setTag(vh);
		} else {
			vh = (ViewHolder) convertView.getTag();
		}
		final Friend friend = getItem(position);
		final User item = friend.getUser();
		if (item.getName() != null) {
			vh.tvName.setText(item.getName());
		} else {
			vh.tvName.setText("XUser");
		}

		final String avatarID = item.getUserInfo().getAvatarID();
		if (avatarID != null) {
			ImageOptions options = new ImageOptions();
			options.round = 5;
			options.fileCache = true;
			options.memCache = true;
			options.targetWidth = 48;
			options.fallback = R.drawable.ic_no_avatar;
			String url = Utils.getSmallAvatarFacebook(avatarID);
			AQuery aq = new AQuery(convertView);
			aq.id(vh.ivAvatar).image(url, options);
			vh.ivAvatar.setOnClickListener(new OnClickListener() {

				@Override
				public void onClick(View v) {
					String avatarLarge = Utils.getLargeAvatarFacebook(avatarID);
					Intent intent = new Intent(context, ViewImageActivity.class);
					intent.putExtra(Common.ExtraKey.IMAGE_URL, avatarLarge);
					context.startActivity(intent);
				}
			});
		} else {
			vh.ivAvatar.setImageResource(R.drawable.ic_no_avatar);
		}

		if (item.getUserInfo().getGender() == GenderType.FEMALE) {
			vh.ivGender.setImageResource(R.drawable.ic_female);
		} else if (item.getUserInfo().getGender() == GenderType.MALE) {
			vh.ivGender.setImageResource(R.drawable.ic_male);
		} else {
			vh.ivGender.setImageResource(R.drawable.ic_other);
		}

		if (friend.isOnline()) {
			vh.ivOnline.setImageResource(R.drawable.ic_online);
			vh.ivOnline.setVisibility(View.VISIBLE);
		} else {
			vh.ivOnline.setImageResource(R.drawable.ic_offline);
			vh.ivOnline.setVisibility(View.GONE);
		}

		if (item.getUserInfo().getStatus() != null) {
			vh.tvStatus.setText(item.getUserInfo().getStatus());
			vh.ibOption.setOnClickListener(new OnClickListener() {

				@Override
				public void onClick(View v) {
					AlertDialog.Builder aBuilder = new AlertDialog.Builder(
							context);
					aBuilder.setItems(
							new String[] { "Copy status", "Report this user",
									"Block this user", "Unfriend" },
							new Dialog.OnClickListener() {
								@Override
								public void onClick(DialogInterface dialog,
										int which) {
									switch (which) {
									case 0:
										Utils.copyTextToClipboard(context, item
												.getUserInfo().getStatus());
										break;
									case 1:
										Utils.reportUser(item.getUserID());
										break;
									case 2:
										blockUser(item.getUserID());
										break;
									case 3:
										unfriend(item.getUserID());
										break;
									default:
										break;
									}
								}
							});

					AlertDialog alertDialog = aBuilder.create();
					alertDialog.setCanceledOnTouchOutside(true);
					alertDialog.show();
				}
			});
		} else {
			vh.tvStatus.setText("");
			vh.ibOption.setOnClickListener(null);
		}

		vh.llSendMessage.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				TargetChat targetChat = new TargetChat(item);
				((MainActivity) context).showChat(targetChat);
			}
		});

		vh.llViewProfile.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				((MainActivity) context).viewProfile(item, true, false);
			}
		});

		return vh.rootView;
	}

	private LayoutInflater mInflater;
	private Context context;
	private List<Friend> data;

	// Constructors
	public FriendsAdapter(Context context, List<Friend> objects) {
		super(context, 0, objects);
		this.mInflater = LayoutInflater.from(context);
		this.context = context;
		this.data = objects;
	}

	public FriendsAdapter(Context context, Friend[] objects) {
		super(context, 0, objects);
		this.mInflater = LayoutInflater.from(context);
		this.context = context;
	}

	private void blockUser(Integer userID) {
		DataManager.getInstance(context)
				.addBlockUsers(Integer.toString(userID));
		for (Friend friend : data) {
			User user = friend.getUser();
			if (user.getUserID().equals(userID)) {
				data.remove(user);
				this.notifyDataSetChanged();
				return;
			}

		}
	}

	private void unfriend(final Integer removedFriendID) {
		QBRequestGetBuilder requestBuilder = new QBRequestGetBuilder();
		requestBuilder.setPagesLimit(1);
		requestBuilder.eq(Common.FriendsObject.USER_ID, DataManager
				.getInstance(context).getCurrentUser().getUserID());
		QBCustomObjects.getObjects(Common.FriendsObject.FRIENDS_CLASS,
				requestBuilder,
				new QBEntityCallbackImpl<ArrayList<QBCustomObject>>() {

					@Override
					public void onSuccess(
							ArrayList<QBCustomObject> customObjects,
							Bundle params) {
						KiraGameLog.d(">>> custom objects: " + customObjects);
						if (customObjects.size() == 0) {

						} else {
							QBCustomObject object = customObjects.get(0);
							Object frObject = object.getFields().get(
									Common.FriendsObject.LIST_FRIENDS);
							if (frObject == null) {
								return;
							}
							String friends = frObject.toString();
							if (friends != null) {
								friends = "/" + friends;
								if (friends.contains("/" + removedFriendID)) {
									friends = friends.replace("/"
											+ removedFriendID, "");
									if (friends.startsWith("/")) {
										friends = friends.substring(1);
									}
								} else {
									return;
								}

							} else {
								return;
							}
							for (Friend friend : data) {
								User user = friend.getUser();
								if (user.getUserID().equals(removedFriendID)) {
									data.remove(user);
									notifyDataSetChanged();
									break;
								}

							}

							HashMap<String, Object> fields = new HashMap<String, Object>();
							fields.put(Common.FriendsObject.LIST_FRIENDS,
									friends);
							object.setFields(fields);
							QBCustomObjects.updateObject(object,
									(QBRequestUpdateBuilder) null,
									new QBEntityCallbackImpl<QBCustomObject>() {
										@Override
										public void onSuccess(
												QBCustomObject object,
												Bundle params) {
											KiraGameLog
													.d(">>> updated record: : "
															+ object.toString());

										}

										@Override
										public void onError(List<String> errors) {
											KiraGameLog
													.d("update getReportUser error "
															+ errors);
										}
									});

						}

					}

					@Override
					public void onError(List<String> errors) {
						KiraGameLog.d("getReportUser error " + errors);
					}
				});
	}

}
